package com.yy.wga.mp.module.income.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.yy.wga.mp.module.income.response.IncomeWithdrawRecordPageResponse;
import com.yy.wga.mp.module.income.service.IncomeWithdrawRecordService;
import com.yy.wga.common.core.exception.BusinessException;
import com.yy.wga.mp.common.interceptor.RequestUserHolder;
import com.yy.wga.mp.common.utils.common.StringUtils;
import com.yy.wga.mp.common.utils.mapping.BeansUtils;
import com.yy.wga.mp.module.admin.request.AdminIncomeWithdrawRecordAuditRequest;
import com.yy.wga.mp.module.admin.request.AdminIncomeWithdrawRecordPageRequest;
import com.yy.wga.mp.module.admin.response.AdminIncomeWithdrawRecordPageResponse;
import com.yy.wga.mp.module.income.entity.pojo.IncomeWithdrawRecordDO;
import com.yy.wga.mp.module.income.mapper.IncomeWithdrawRecordMapper;
import com.yy.wga.mp.module.pay.event.TransferCallbackEvent;
import com.yy.wga.mp.module.pay.manager.PayManager;
import com.yy.wga.mp.module.pay.request.TransferRequest;
import com.yy.wga.mp.module.pay.response.TransferResponse;
import com.yy.wga.mp.module.user.entity.pojo.UserBaseDO;
import com.yy.wga.mp.module.user.service.UserBaseService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户提现记录(IncomeWithdrawRecord)表服务实现类
 *
 * @author guochao
 * @since 2024-11-12 00:27:49
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class IncomeWithdrawRecordServiceImpl extends ServiceImpl<IncomeWithdrawRecordMapper, IncomeWithdrawRecordDO> implements IncomeWithdrawRecordService {
    private final UserBaseService userBaseService;
    private final PayManager payManager;
    private final ApplicationEventPublisher eventPublisher;

    @Override
    public List<IncomeWithdrawRecordPageResponse> list(BasePageRequestDTO request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), false);
        List<IncomeWithdrawRecordDO> withdrawRecordList = baseMapper.selectList(new LambdaQueryWrapper<IncomeWithdrawRecordDO>()
                .eq(IncomeWithdrawRecordDO::getAppKey, RequestUserHolder.getBaseRequest().getAppKey())
                .eq(IncomeWithdrawRecordDO::getUserId, RequestUserHolder.getUserCache().getUserId())
                .orderByDesc(IncomeWithdrawRecordDO::getId));
        return BeansUtils.mapList(withdrawRecordList, IncomeWithdrawRecordPageResponse.class);
    }

    @Override
    public PageBean<AdminIncomeWithdrawRecordPageResponse> pageData(AdminIncomeWithdrawRecordPageRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<IncomeWithdrawRecordDO> withdrawRecordList = baseMapper.selectList(new LambdaQueryWrapper<IncomeWithdrawRecordDO>()
                .eq(IncomeWithdrawRecordDO::getAppKey, RequestUserHolder.getBaseRequest().getAppKey())
                .eq(request.getStatus() != null, IncomeWithdrawRecordDO::getStatus, request.getStatus())
                .eq(StringUtils.isNotBlank(request.getOrderNo()), IncomeWithdrawRecordDO::getOrderNo, request.getOrderNo())
                .eq(StringUtils.isNotBlank(request.getWithdrawAccount()), IncomeWithdrawRecordDO::getWithdrawAccount, request.getWithdrawAccount())
                .orderByDesc(IncomeWithdrawRecordDO::getId));
        if (CollectionUtils.isEmpty(withdrawRecordList)) {
            PageBean<AdminIncomeWithdrawRecordPageResponse> pageBean = new PageBean<>();
            pageBean.setPageNum(request.getPageNum());
            pageBean.setPageSize(request.getPageSize());
            return pageBean;
        }

        List<AdminIncomeWithdrawRecordPageResponse> responseList = BeansUtils.mapList(withdrawRecordList, AdminIncomeWithdrawRecordPageResponse.class);
        // 查询用户
        List<UserBaseDO> userBaseList = userBaseService.list(new LambdaQueryWrapper<UserBaseDO>()
                .eq(UserBaseDO::getAppKey, RequestUserHolder.getBaseRequest().getAppKey())
                .eq(UserBaseDO::getId, responseList.stream()
                        .map(AdminIncomeWithdrawRecordPageResponse::getUserId)
                        .collect(Collectors.toSet())));
        Map<Long, UserBaseDO> userBaseMap = userBaseList.stream()
                .collect(Collectors.toMap(UserBaseDO::getId, Function.identity()));
        for (AdminIncomeWithdrawRecordPageResponse response : responseList) {
            UserBaseDO userBase = userBaseMap.get(response.getUserId());
            if (userBase != null) {
                response.setPhone(userBase.getPhone());
            }
        }

        PageBean<AdminIncomeWithdrawRecordPageResponse> pageBean = new PageBean<>();
        pageBean.setPageInfo(withdrawRecordList);
        pageBean.setList(responseList);
        return pageBean;
    }

    @Override
    @Transactional
    public void audit(AdminIncomeWithdrawRecordAuditRequest request) {
        IncomeWithdrawRecordDO withdrawRecord = this.getById(request.getId());
        if (withdrawRecord == null) {
            throw new BusinessException("数据不存在");
        }
        // 提现拒绝
        if (request.getStatus() == 1) {
            // 发送事件
            TransferCallbackEvent transferCallbackEvent = new TransferCallbackEvent();
            transferCallbackEvent.setAppKey(RequestUserHolder.getBaseRequest().getAppKey());
            transferCallbackEvent.setOutBatchNo(withdrawRecord.getOrderNo());
            transferCallbackEvent.setBatchStatus("CLOSED");
            transferCallbackEvent.setCloseReason(request.getReason());
            eventPublisher.publishEvent(transferCallbackEvent);
        } else {
            // 转账
            TransferRequest transferRequest = new TransferRequest();
            transferRequest.setOrderNo(withdrawRecord.getOrderNo());
            transferRequest.setAmount(withdrawRecord.getAmount());
            transferRequest.setChannelType(withdrawRecord.getType());
            transferRequest.setOpenId(withdrawRecord.getOpenId());
            transferRequest.setName(withdrawRecord.getRealName());
            transferRequest.setWithdrawAccount(withdrawRecord.getWithdrawAccount());
            transferRequest.setUserId(withdrawRecord.getUserId());
            transferRequest.setOrderTitle("收益提现");
            transferRequest.setIdentityType(2);
            TransferResponse transferResponse = payManager.transfer(transferRequest);
            // 提现状态 0、提现中 1、提现成功 2、提现失败
            Integer status = transferResponse.getStatus();

            // 提现中不用修改余额等操作
            if (status == 0) {
                return;
            }

            // 发送事件
            TransferCallbackEvent transferCallbackEvent = new TransferCallbackEvent();
            transferCallbackEvent.setAppKey(RequestUserHolder.getBaseRequest().getAppKey());
            transferCallbackEvent.setOutBatchNo(withdrawRecord.getOrderNo());
            if (status == 1) {
                transferCallbackEvent.setBatchStatus("FINISHED");
            } else {
                transferCallbackEvent.setBatchStatus("CLOSED");
                transferCallbackEvent.setCloseReason(transferResponse.getFailReason());
            }
            eventPublisher.publishEvent(transferCallbackEvent);
        }
    }
}
